﻿using TrueSync;

namespace HEFramework
{
    public static class SkillComponentSystem
    {
        [EntitySystem]
        public class SkillComponentAwakeSystem : AwakeSystem<SkillComponent>
        {
            protected override void Awake(SkillComponent _self)
            {
                var ac = _self.GetParentChild<AttributeComponent>();
                if (ac == null)
                {
                    return;
                }

                _self.AddChild<SkillPreparationComponent>();
                _self.AddChild<SkillExecutionComponent>();
                _self.AddChild<SkillCooldownComponent>();
                _self.AddChild<SkillCastComponent>();
                _self.AddChild<SkillLockComponent>();
                _self.AddChild<SkillRangeComponent>();
                _self.AddChild<SkillResourceComponent>();
                _self.AddChild<SkillEffectComponent>();


                for (int i = 0; i < ac.Attribute.SKILLS.Length; i++)
                {
                    int id = ac.Attribute.SKILLS[i];
                    if (id == 0 || id == -1)
                    {
                        continue;
                    }

                    _self.AddSkill(id);
                }
            }
        }

        public static void AddSkill(this SkillComponent _self, int _id)
        {
            var sec = _self.GetChild<SkillExecutionComponent>();
            if (sec == null)
            {
                return;
            }

            sec.AddSkill(_id);
        }

        public static void RemoveSkill(this SkillComponent _self, int _id)
        {
            var sec = _self.GetChild<SkillExecutionComponent>();
            if (sec == null)
            {
                return;
            }

            sec.RemoveSkill(_id);
        }

        public static void TriggerActiveSkill(this SkillComponent _self, int _id)
        {
            var receiver = _self.GetMainEntity();
            var tc = receiver.GetChild<TransformComponent>();
            if (tc == null)
            {
                return;
            }

            _self.TriggerActiveSkill(_id, receiver, tc.P);
        }

        public static void TriggerPassiveSkill(this SkillComponent _self, eSkillTriggerType _type)
        {
            var receiver = _self.GetMainEntity();
            var tc = receiver.GetChild<TransformComponent>();
            if (tc == null)
            {
                return;
            }

            _self.TriggerPassiveSkill(_type, receiver, tc.P);
        }

        public static void TriggerActiveSkill(this SkillComponent _self, int _id, Entity _receiver)
        {
            var tc = _receiver.GetChild<TransformComponent>();
            if (tc == null)
            {
                return;
            }

            _self.TriggerActiveSkill(_id, _receiver, tc.P);
        }

        public static void TriggerPassiveSkill(this SkillComponent _self, eSkillTriggerType _type, Entity _receiver)
        {
            var tc = _receiver.GetChild<TransformComponent>();
            if (tc == null)
            {
                return;
            }

            _self.TriggerPassiveSkill(_type, _receiver, tc.P);
        }

        public static void TriggerActiveSkill(this SkillComponent _self, int _id, Entity _receiver, TSVector _pos)
        {
            var sec = _self.GetChild<SkillExecutionComponent>();
            if (sec == null)
            {
                return;
            }

            sec.TriggerActiveSkill(_id, _receiver, _pos);
        }

        public static void TriggerPassiveSkill(this SkillComponent _self, eSkillTriggerType _type, Entity _receiver, TSVector _pos)
        {
            var sec = _self.GetChild<SkillExecutionComponent>();
            if (sec == null)
            {
                return;
            }

            sec.TriggerPassiveSkill(_type, _receiver, _pos);
        }


        public static void ExecuteSkillEffect(this SkillComponent _self, int _id)
        {
            _self.ExecuteSkillEffect(_id, _self.GetMainEntity(), _self.GetMainEntityPos());
        }

        public static void RemoveSkillEffect(this SkillComponent _self, int _id)
        {
            _self.RemoveSkillEffect(_id, _self.GetMainEntity(), _self.GetMainEntityPos());
        }

        public static void DestroySkillEffect(this SkillComponent _self, int _id)
        {
            _self.DestroySkillEffect(_id, _self.GetMainEntity(), _self.GetMainEntityPos());
        }

        public static void ExecuteSkillEffect(this SkillComponent _self, int _id, Entity _receiver, TSVector _pos)
        {
            var sec = _self.GetChild<SkillEffectComponent>();
            if (sec == null)
            {
                return;
            }

            sec.Execute(_id, _receiver, _pos);
        }

        public static void RemoveSkillEffect(this SkillComponent _self, int _id, Entity _receiver, TSVector _pos)
        {
            var sec = _self.GetChild<SkillEffectComponent>();
            if (sec == null)
            {
                return;
            }

            sec.Remove(_id, _receiver, _pos);
        }

        public static void DestroySkillEffect(this SkillComponent _self, int _id, Entity _receiver, TSVector _pos)
        {
            var sec = _self.GetChild<SkillEffectComponent>();
            if (sec == null)
            {
                return;
            }

            sec.Destroy(_id, _receiver, _pos);
        }

        public static object GetSkillEffect(this SkillComponent _self, int _id)
        {
            var sec = _self.GetChild<SkillEffectComponent>();
            if (sec == null)
            {
                return null;
            }

            return sec.GetBuff(_id);
        }


        public static FP Skill_CD(this SkillComponent _self, int _id, bool _isActive)
        {
            var scc = _self.GetChild<SkillCooldownComponent>();
            if (scc == null)
            {
                return 0;
            }

            return scc.Skill_CD(_id, _isActive);
        }

        public static FP Skill_CD_PCT(this SkillComponent _self, int _id, bool _isActive)
        {
            var scc = _self.GetChild<SkillCooldownComponent>();
            if (scc == null)
            {
                return 0;
            }

            return scc.Sill_CD_PCT(_id, _isActive);
        }

        public static FP Skill_Cost(this SkillComponent _self, int _id, bool _isActive, int _type)
        {
            var src = _self.GetChild<SkillResourceComponent>();
            if (src == null)
            {
                return 0;
            }

            return src.Skill_Cost(_id, _isActive, _type);
        }

        public static bool IsLock(this SkillComponent _self, int _id)
        {
            var scl = _self.GetChild<SkillLockComponent>();
            if (scl == null)
            {
                return true;
            }

            if (scl.Ready(_id) == (int)eSkillErrorCode.None)
            {
                return false;
            }

            return true;
        }

        public static Entity GetMainEntity(this SkillComponent _self)
        {
            return _self.Parent;
        }

        public static TSVector GetMainEntityPos(this SkillComponent _self)
        {
            var entity = _self.GetMainEntity();
            var tc = entity.GetChild<TransformComponent>();
            if (tc == null)
            {
                return new TSVector();
            }

            return tc.P;
        }
    }
}